home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / MAKEMON.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  33KB  |  1,295 lines

  1. /*    SCCS Id: @(#)makemon.c    3.0    89/11/22
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #ifdef REINCARNATION
  7. # include <ctype.h>
  8. #endif
  9.  
  10. STATIC_VAR struct monst NEARDATA zeromonst;
  11.  
  12. #ifdef OVL0
  13. static int NDECL(cmnum);
  14. static int FDECL(uncommon, (struct permonst *));
  15. #endif /* OVL0 */
  16. STATIC_DCL void FDECL(m_initgrp,(struct monst *,int,int,int));
  17. STATIC_DCL void FDECL(m_initthrow,(struct monst *,int,int));
  18. STATIC_DCL void FDECL(m_initweap,(struct monst *));
  19. STATIC_DCL void FDECL(rloc_to,(struct monst *,int,int));
  20. #ifdef OVL1
  21. static void FDECL(m_initinv,(struct monst *));
  22. static int FDECL(mstrength,(struct permonst *));
  23. #endif /* OVL1 */
  24.  
  25. extern int monstr[];
  26.  
  27. #ifdef OVLB
  28.  
  29. int monstr[NUMMONS];
  30.  
  31. #endif /* OVLB */
  32.  
  33. #define m_initsgrp(mtmp, x, y)    m_initgrp(mtmp, x, y, 3)
  34. #define m_initlgrp(mtmp, x, y)    m_initgrp(mtmp, x, y, 10)
  35. #define toostrong(monindx, lev) (monstr[monindx] > lev)
  36. #define tooweak(monindx, lev)    (monstr[monindx] < lev)
  37.  
  38. #ifdef OVLB
  39.  
  40. STATIC_OVL void
  41. m_initgrp(mtmp, x, y, n)    /* make a group just like mtmp */
  42. register struct monst *mtmp;
  43. register int x, y, n;
  44. {
  45.     coord mm;
  46.     register int cnt = rnd(n);
  47.     struct monst *mon;
  48.  
  49. /*
  50.  *    Temporary kludge to cut down on swarming at lower character levels
  51.  *    till we can get this game a little more balanced. [mrs]
  52.  */
  53.     cnt /= (u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1;
  54.     if(!cnt) cnt++;
  55.  
  56.     mm.x = x;
  57.     mm.y = y;
  58.     while(cnt--) {
  59.         if (peace_minded(mtmp->data)) continue;
  60.         /* Don't create groups of peaceful monsters since they'll get
  61.          * in our way.  If the monster has a percentage chance so some
  62.          * are peaceful and some are not, the result will just be a
  63.          * smaller group.
  64.          */
  65.         if (enexto(&mm, mm.x, mm.y, mtmp->data)) {
  66.             mon = makemon(mtmp->data, mm.x, mm.y);
  67.             mon->mpeaceful = 0;
  68.             set_malign(mon);
  69.             /* Undo the second peace_minded() check in makemon(); if the
  70.              * monster turned out to be peaceful the first time we
  71.              * didn't create it at all; we don't want a second check.
  72.              */
  73.         }
  74.     }
  75. }
  76.  
  77. STATIC_OVL
  78. void
  79. m_initthrow(mtmp,otyp,oquan)
  80. struct monst *mtmp;
  81. int otyp,oquan;
  82. {
  83.     register struct obj *otmp;
  84.  
  85.     otmp = mksobj(otyp,FALSE);
  86.     otmp->quan = 2 + rnd(oquan);
  87.     otmp->owt = weight(otmp);
  88. #ifdef TOLKIEN
  89.     if (otyp == ORCISH_ARROW) otmp->opoisoned = 1;
  90. #endif
  91.     mpickobj(mtmp, otmp);
  92. }
  93.  
  94. #endif /* OVLB */
  95. #ifdef OVL2
  96.  
  97. STATIC_OVL void
  98. m_initweap(mtmp)
  99. register struct monst *mtmp;
  100. {
  101.     register struct permonst *ptr = mtmp->data;
  102.     register int mm = monsndx(ptr);
  103. #ifdef REINCARNATION
  104.     if (dlevel==rogue_level) return;
  105. #endif
  106. /*
  107.  *    first a few special cases:
  108.  *
  109.  *        giants get a boulder to throw sometimes.
  110.  *        ettins get clubs
  111.  *        kobolds get darts to throw
  112.  *        centaurs get some sort of bow & arrows or bolts
  113.  *        soldiers get all sorts of things.
  114.  *        kops get clubs & cream pies.
  115.  */
  116.     switch (mtmp->data->mlet) {
  117.         case S_GIANT:
  118.         if (rn2(2)) (void)mongets(mtmp, (ptr != &mons[PM_ETTIN]) ?
  119.                     BOULDER : CLUB);
  120.         break;
  121.         case S_HUMAN:
  122.         if(is_mercenary(ptr))
  123.             switch (mm) {
  124.  
  125. #ifdef ARMY
  126.             case PM_SOLDIER:
  127.               (void) mongets(mtmp, rn2(2) ? SPEAR : SHORT_SWORD);
  128.               break;
  129.             case PM_SERGEANT:
  130.               (void) mongets(mtmp, rn2(2) ? FLAIL : MACE);
  131.               break;
  132.             case PM_LIEUTENANT:
  133.               (void) mongets(mtmp, rn2(2) ? GLAIVE : LONG_SWORD);
  134.               break;
  135.             case PM_CAPTAIN:
  136.               (void) mongets(mtmp, rn2(2) ? LONG_SWORD : SCIMITAR);
  137.               break;
  138. #endif
  139.             default:    if (!rn2(4)) (void) mongets(mtmp, DAGGER);
  140.                     if (!rn2(7)) (void) mongets(mtmp, SPEAR);
  141.                     break;
  142.             }
  143.             break;
  144.  
  145.         case S_HUMANOID:
  146. #ifdef TOLKIEN
  147.         if (mm == PM_HOBBIT) {
  148.             switch (rn2(3)) {
  149.             case 0:
  150.                 (void)mongets(mtmp, DAGGER);
  151.                 break;
  152.             case 1:
  153.                 (void)mongets(mtmp, ELVEN_DAGGER);
  154.                 break;
  155.             case 2:
  156.                 (void)mongets(mtmp, SLING);
  157.                 break;
  158.               }
  159.             if (!rn2(10)) (void)mongets(mtmp, ELVEN_MITHRIL_COAT);
  160.         } else if (is_dwarf(ptr)) {
  161.             (void)mongets(mtmp, DWARVISH_CLOAK);
  162.             (void)mongets(mtmp, IRON_SHOES);
  163.             if (!rn2(4)) {
  164.             (void)mongets(mtmp, DWARVISH_SHORT_SWORD);
  165.             /* note: you can't use a mattock with a shield */
  166.             if (rn2(2)) (void)mongets(mtmp, DWARVISH_MATTOCK);
  167.             else {
  168.                 (void)mongets(mtmp, AXE);
  169.                 (void)mongets(mtmp, DWARVISH_ROUNDSHIELD);
  170.             }
  171.             (void)mongets(mtmp, DWARVISH_IRON_HELM);
  172.             if (!rn2(3))
  173.                 (void)mongets(mtmp, DWARVISH_MITHRIL_COAT);
  174.             } else {
  175.             (void)mongets(mtmp, PICK_AXE);
  176.             }
  177.         } else if (is_elf(ptr)) {
  178.             (void)mongets(mtmp,
  179.             rn2(2) ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
  180.             if (rn2(2)) (void)mongets(mtmp, ELVEN_LEATHER_HELM);
  181.             if (rn2(3)) (void)mongets(mtmp, ELVEN_DAGGER);
  182.             switch (rn2(3)) {
  183.             case 0:
  184.                 if (!rn2(4)) (void)mongets(mtmp, ELVEN_SHIELD);
  185.                 (void)mongets(mtmp, ELVEN_SHORT_SWORD);
  186.                 (void)mongets(mtmp, ELVEN_BOW);
  187.                 m_initthrow(mtmp, ELVEN_ARROW, 12);
  188.                 break;
  189.             case 1:
  190.                 (void)mongets(mtmp, ELVEN_BROADSWORD);
  191.                 if (rn2(2)) (void)mongets(mtmp, ELVEN_SHIELD);
  192.                 break;
  193.             case 2:
  194.                 (void)mongets(mtmp, ELVEN_SPEAR);
  195.                 (void)mongets(mtmp, ELVEN_SHIELD);
  196.                 break;
  197.             }
  198.         }
  199. #else /* TOLKIEN */
  200.         if (is_dwarf(ptr)) {
  201.             (void)mongets(mtmp, IRON_SHOES);
  202.             if (rn2(4) == 0) {
  203.             (void)mongets(mtmp, SHORT_SWORD);
  204.             if (rn2(2)) (void)mongets(mtmp, TWO_HANDED_SWORD);
  205.             else {
  206.                 (void)mongets(mtmp, AXE);
  207.                 (void)mongets(mtmp, LARGE_SHIELD);
  208.             }
  209.             if (rn2(3) == 0)
  210.                 (void)mongets(mtmp, DWARVISH_MITHRIL_COAT);
  211.             } else {
  212.             (void)mongets(mtmp, PICK_AXE);
  213.             }
  214.         } else if (is_elf(ptr)) {
  215.             (void)mongets(mtmp, ELVEN_CLOAK);
  216.             if (rn2(3)) (void)mongets(mtmp, DAGGER);
  217.             switch (rn2(3)) {
  218.             case 0:
  219.                 if (!rn2(4)) (void)mongets(mtmp, SMALL_SHIELD);
  220.                 (void)mongets(mtmp, SHORT_SWORD);
  221.                 (void)mongets(mtmp, BOW);
  222.                 m_initthrow(mtmp, ARROW, 12);
  223.                 break;
  224.             case 1:
  225.                 (void)mongets(mtmp, BROADSWORD);
  226.                 if (rn2(2)) (void)mongets(mtmp, SMALL_SHIELD);
  227.                 break;
  228.             case 2:
  229.                 (void)mongets(mtmp, SPEAR);
  230.                 (void)mongets(mtmp, SMALL_SHIELD);
  231.                 break;
  232.             }
  233.         }
  234. #endif /* TOLKIEN */
  235.         break;
  236. # ifdef KOPS
  237.         case S_KOP:        /* create Keystone Kops with cream pies to
  238.                  * throw. As suggested by KAA.       [MRS]
  239.                  */
  240.         if (!rn2(4)) m_initthrow(mtmp, CREAM_PIE, 2);
  241.         if (!rn2(3)) (void)mongets(mtmp, (rn2(2)) ? CLUB : RUBBER_HOSE);
  242.         break;
  243. #endif
  244.         case S_ORC:
  245.         if(rn2(2)) (void)mongets(mtmp, ORCISH_HELM);
  246. #ifdef TOLKIEN
  247.         switch (mm != PM_ORC_CAPTAIN ? mm :
  248.             rn2(2) ? PM_MORDOR_ORC : PM_URUK_HAI) {
  249.             case PM_MORDOR_ORC:
  250.             if(rn2(2)) (void)mongets(mtmp, SCIMITAR);
  251.             if(rn2(2)) (void)mongets(mtmp, ORCISH_SHIELD);
  252.             if(rn2(2)) (void)mongets(mtmp, KNIFE);
  253.             if(rn2(2)) (void)mongets(mtmp, ORCISH_CHAIN_MAIL);
  254.             break;
  255.             case PM_URUK_HAI:
  256.             if(rn2(2)) (void)mongets(mtmp, ORCISH_CLOAK);
  257.             if(rn2(2)) (void)mongets(mtmp, ORCISH_SHORT_SWORD);
  258.             if(rn2(2)) (void)mongets(mtmp, IRON_SHOES);
  259.             if(rn2(2)) {
  260.                 (void)mongets(mtmp, ORCISH_BOW);
  261.                 m_initthrow(mtmp, ORCISH_ARROW, 12);
  262.             }
  263.             if(rn2(2)) (void)mongets(mtmp, URUK_HAI_SHIELD);
  264.             break;
  265.             default:
  266.             if (mm != PM_ORC_SHAMAN)
  267.               (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0) ?
  268.                           ORCISH_DAGGER : SCIMITAR);
  269. #else /* TOLKIEN */
  270.         switch (mm) {
  271.             case  PM_ORC_CAPTAIN:
  272.             if(rn2(2)) {
  273.                 if(rn2(2)) (void)mongets(mtmp, SCIMITAR);
  274.                 if(rn2(2)) (void)mongets(mtmp, SMALL_SHIELD);
  275.                 if(rn2(2)) (void)mongets(mtmp, KNIFE);
  276.                 if(rn2(2)) (void)mongets(mtmp, CHAIN_MAIL);
  277.             } else {
  278.                 if(rn2(2)) (void)mongets(mtmp, SHORT_SWORD);
  279.                 if(rn2(2)) (void)mongets(mtmp, IRON_SHOES);
  280.                 if(rn2(2)) {
  281.                 (void)mongets(mtmp, BOW);
  282.                 m_initthrow(mtmp, ARROW, 12);
  283.                 }
  284.                 if(rn2(2)) (void)mongets(mtmp, SMALL_SHIELD);
  285.             }
  286.             default:
  287.             if (mm != PM_ORC_SHAMAN)
  288.               (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0) ?
  289.                           DAGGER : SCIMITAR);
  290. #endif /* TOLKIEN */
  291.         }
  292.         break;
  293.         case S_KOBOLD:
  294.         if (!rn2(4)) m_initthrow(mtmp, DART, 12);
  295.         break;
  296.  
  297.         case S_CENTAUR:
  298.         if (rn2(2)) {
  299.             if(ptr == &mons[PM_FOREST_CENTAUR]) {
  300.             (void)mongets(mtmp, BOW);
  301.             m_initthrow(mtmp, ARROW, 12);
  302.             } else {
  303.             (void)mongets(mtmp, CROSSBOW);
  304.             m_initthrow(mtmp, CROSSBOW_BOLT, 12);
  305.             }
  306.         }
  307.         break;
  308.         case S_WRAITH:
  309.         (void)mongets(mtmp, KNIFE);
  310.         (void)mongets(mtmp, LONG_SWORD);
  311.         break;
  312.         case S_DEMON:
  313. #ifdef INFERNO
  314.         switch (mm) {
  315.             case PM_BALROG:
  316.             (void)mongets(mtmp, BULLWHIP);
  317.             (void)mongets(mtmp, BROADSWORD);
  318.             break;
  319.             case PM_ORCUS:
  320.             (void)mongets(mtmp, WAN_DEATH); /* the Wand of Orcus */
  321.             break;
  322.             case PM_HORNED_DEVIL:
  323.             (void)mongets(mtmp, rn2(4) ? TRIDENT : BULLWHIP);
  324.             break;
  325.             case PM_ICE_DEVIL:
  326.             if (!rn2(4)) (void)mongets(mtmp, SPEAR);
  327.             break;
  328.             case PM_ASMODEUS:
  329.             (void)mongets(mtmp, WAN_COLD);
  330.             break;
  331.             case PM_DISPATER:
  332.             (void)mongets(mtmp, WAN_STRIKING);
  333.             break;
  334.             case PM_YEENOGHU:
  335.             (void)mongets(mtmp, FLAIL);
  336.             break;
  337.         }
  338. #endif
  339.         /* prevent djinnis and mail daemons from leaving objects when
  340.          * they vanish
  341.          */
  342.         if (!is_demon(ptr)) break;
  343.         /* fall thru */
  344. /*
  345.  *    Now the general case, ~40% chance of getting some type
  346.  *    of weapon. TODO: Add more weapons types (use bigmonst());
  347.  */
  348.         default:
  349.         switch(rnd(12)) {
  350.             case 1:
  351.             m_initthrow(mtmp, DART, 12);
  352.             break;
  353.             case 2:
  354.             (void) mongets(mtmp, CROSSBOW);
  355.             m_initthrow(mtmp, CROSSBOW_BOLT, 12);
  356.             break;
  357.             case 3:
  358.             (void) mongets(mtmp, BOW);
  359.             m_initthrow(mtmp, ARROW, 12);
  360.             break;
  361.             case 4:
  362.             m_initthrow(mtmp, DAGGER, 3);
  363.             break;
  364.             case 5:
  365.             (void) mongets(mtmp, AKLYS);
  366.             break;
  367.             default:
  368.             break;
  369.         }
  370.         break;
  371.     }
  372. }
  373.  
  374. #endif /* OVL2 */
  375. #ifdef OVL1
  376.  
  377. static void
  378. m_initinv(mtmp)
  379. register struct    monst    *mtmp;
  380. {
  381.     register int cnt;
  382.     register struct obj *otmp;
  383.     register struct permonst *ptr = mtmp->data;
  384. #ifdef REINCARNATION
  385.     if (dlevel==rogue_level) return;
  386. #endif
  387. /*
  388.  *    Soldiers get armour & rations - armour approximates their ac.
  389.  *    Nymphs may get mirror or potion of object detection.
  390.  */
  391.     switch(mtmp->data->mlet) {
  392.  
  393.         case S_HUMAN:
  394.         if(is_mercenary(ptr)) {
  395.             register int mac;
  396.  
  397.             if((mac = ptr->ac) < -1)
  398.             mac += 7 + mongets(mtmp, (rn2(5)) ?
  399.                        PLATE_MAIL : CRYSTAL_PLATE_MAIL);
  400.             else if(mac < 3)
  401.             mac += 6 + mongets(mtmp, (rn2(3)) ?
  402.                        SPLINT_MAIL : BANDED_MAIL);
  403.             else
  404.             mac += 3 + mongets(mtmp, (rn2(3)) ?
  405.                        RING_MAIL : STUDDED_LEATHER_ARMOR);
  406.  
  407.             if(mac < 10) {
  408.             mac += 1 + mongets(mtmp, HELMET);
  409.             if(mac < 10) {
  410.                 mac += 1 + mongets(mtmp, SMALL_SHIELD);
  411.                 if(mac < 10) {
  412.                 mac += 1 + mongets(mtmp, ELVEN_CLOAK);
  413.                 if(mac < 10)
  414.                     mac += 1 +mongets(mtmp, LEATHER_GLOVES);
  415.                 }
  416.             }
  417.             }
  418.  
  419.             if(mac != 10) {    /* make up the difference */
  420.             otmp = mksobj(RIN_PROTECTION,FALSE);
  421.             otmp->spe = (10 - mac);
  422.             if(otmp->spe < 0) curse(otmp);
  423.             mpickobj(mtmp, otmp);
  424.             }
  425. #ifdef ARMY
  426.             if(ptr != &mons[PM_GUARD]) {
  427.             if (!rn2(3)) (void) mongets(mtmp, K_RATION);
  428.             if (!rn2(2)) (void) mongets(mtmp, C_RATION);
  429.             }
  430. #endif
  431.         } else if (ptr == &mons[PM_SHOPKEEPER]) {
  432.             (void) mongets(mtmp,SKELETON_KEY);
  433.         }
  434.         break;
  435.  
  436.         case S_NYMPH:
  437. #ifdef MEDUSA
  438.         if(!rn2(2)) (void) mongets(mtmp, MIRROR);
  439. #endif
  440.         if(!rn2(2)) (void) mongets(mtmp, POT_OBJECT_DETECTION);
  441.         break;
  442.  
  443.         case S_GIANT:
  444.         if(mtmp->data == &mons[PM_MINOTAUR])
  445.             (void) mongets(mtmp, WAN_DIGGING);
  446.         else if (is_giant(mtmp->data)) {
  447.             for(cnt = rn2((int)(mtmp->m_lev / 2)); cnt; cnt--) {
  448.                 do
  449.                 otmp = mkobj(GEM_SYM,FALSE);
  450.                 while (otmp->otyp >= LAST_GEM+6);
  451.                 otmp->quan = 2 + rnd(2);
  452.                 otmp->owt = weight(otmp);
  453.                 mpickobj(mtmp, otmp);
  454.             }
  455.         }
  456.         break;
  457. #ifdef TOLKIEN
  458.         case S_WRAITH:
  459.         if(mtmp->data == &mons[PM_NAZGUL]) {
  460.             otmp = mksobj(RIN_INVISIBILITY, FALSE);
  461.             curse(otmp);
  462.             mpickobj(mtmp, otmp);
  463.         }
  464.         break;
  465. #endif
  466.         default:
  467.         break;
  468.     }
  469. }
  470.  
  471. /*
  472.  * called with [x,y] = coordinates;
  473.  *    [0,0] means anyplace
  474.  *    [u.ux,u.uy] means: near player (if !in_mklev)
  475.  *
  476.  *    In case we make a monster group, only return the one at [x,y].
  477.  */
  478. struct monst *
  479. makemon(ptr, x, y)
  480. register struct permonst *ptr;
  481. register int    x, y;
  482. {
  483.     register struct monst *mtmp;
  484.     register int    ct;
  485.     boolean anything = (!ptr);
  486.     boolean byyou = (x == u.ux && y == u.uy);
  487.  
  488.     /* if caller wants random location, do it here */
  489.     if(x == 0 && y == 0) {
  490.         int uroom;
  491.         int tryct = 0;    /* careful with bigrooms */
  492. #ifdef __GNULINT__
  493.         uroom = 0;    /* supress used before set warning */
  494. #endif
  495.         if(!in_mklev) uroom = inroom(u.ux, u.uy);
  496.  
  497.         do {
  498.             x = rn1(COLNO-3,2);
  499.             y = rn2(ROWNO);
  500.         } while(!goodpos(x, y, ptr) ||
  501.             (!in_mklev && tryct++ < 50 && inroom(x, y) == uroom));
  502.     } else if (byyou && !in_mklev) {
  503.         coord bypos;
  504.  
  505.         if(enexto(&bypos, u.ux, u.uy, ptr)) {
  506.             x = bypos.x;
  507.             y = bypos.y;
  508.         } else
  509.             return((struct monst *)0);
  510.     }
  511.  
  512.     /* if a monster already exists at the position, return */
  513.     if(MON_AT(x, y))
  514.         return((struct monst *) 0);
  515.  
  516.     if(ptr){
  517.         /* if you are to make a specific monster and it has
  518.            already been genocided, return */
  519.         if(ptr->geno & G_GENOD) return((struct monst *) 0);
  520.     } else {
  521.         /* make a random (common) monster. */
  522.         if(!(ptr = rndmonst()))
  523.         {
  524. #ifdef DEBUG
  525.             pline("Warning: no monster.");
  526. #endif
  527.             return((struct monst *) 0);    /* no more monsters! */
  528.         }
  529.     }
  530.     /* if it's unique, don't ever make it again */
  531.     if (ptr->geno & G_UNIQ) ptr->geno |= G_GENOD;
  532. /* gotmon:    /* label not referenced */
  533.     mtmp = newmonst(ptr->pxlth);
  534.     *mtmp = zeromonst;        /* clear all entries in structure */
  535.     for(ct = 0; ct < ptr->pxlth; ct++)
  536.         ((char *) &(mtmp->mextra[0]))[ct] = 0;
  537.     mtmp->nmon = fmon;
  538.     fmon = mtmp;
  539.     mtmp->m_id = flags.ident++;
  540.     mtmp->data = ptr;
  541.     mtmp->mxlth = ptr->pxlth;
  542.  
  543.     mtmp->m_lev = adj_lev(ptr);
  544. #ifdef GOLEMS
  545.     if (is_golem(ptr))
  546.         mtmp->mhpmax = mtmp->mhp = golemhp(monsndx(ptr));
  547.     else
  548. #endif /* GOLEMS */
  549.     if(ptr->mlevel > 49) {
  550.         /* "special" fixed hp monster
  551.          * the hit points are encoded in the mlevel in a somewhat strange
  552.          * way to fit in the 50..127 positive range of a signed character
  553.          * above the 1..49 that indicate "normal" monster levels */
  554.         mtmp->mhpmax = mtmp->mhp = 2*(ptr->mlevel - 6);
  555.         mtmp->m_lev = mtmp->mhp / 4;    /* approximation */
  556.     } else if((ptr->mlet == S_DRAGON) && (ptr >= &mons[PM_GRAY_DRAGON]))
  557.         mtmp->mhpmax = mtmp->mhp = 80;
  558.     else if(!mtmp->m_lev) mtmp->mhpmax = mtmp->mhp = rnd(4);
  559.     else mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, 8);
  560.     place_monster(mtmp, x, y);
  561.     mtmp->mcansee = mtmp->mcanmove = 1;
  562.     mtmp->mpeaceful = peace_minded(ptr);
  563.  
  564.     switch(ptr->mlet) {
  565.         case S_MIMIC:
  566.             set_mimic_sym(mtmp);
  567.             break;
  568.         case S_SPIDER:
  569.         case S_SNAKE:
  570.             mtmp->mhide = 1;
  571.             if(in_mklev)
  572.                 if(x && y)
  573.                 (void) mkobj_at(0, x, y, TRUE);
  574.             if(OBJ_AT(x, y) || levl[x][y].gmask)
  575.                 mtmp->mundetected = 1;
  576.             break;
  577.         case S_STALKER:
  578.         case S_EEL:
  579.             mtmp->minvis = 1;
  580.             break;
  581.         case S_LEPRECHAUN:
  582.             mtmp->msleep = 1;
  583.             break;
  584.         case S_JABBERWOCK:
  585.         case S_NYMPH:
  586.             if(rn2(5) && !u.uhave_amulet) mtmp->msleep = 1;
  587.             break;
  588.         case S_UNICORN:
  589.             if ((ptr==&mons[PM_WHITE_UNICORN] &&
  590.                 u.ualigntyp == U_LAWFUL) ||
  591.             (ptr==&mons[PM_GRAY_UNICORN] &&
  592.                 u.ualigntyp == U_NEUTRAL) ||
  593.             (ptr==&mons[PM_BLACK_UNICORN] &&
  594.                 u.ualigntyp == U_CHAOTIC))
  595.                 mtmp->mpeaceful = 1;
  596.             break;
  597.     }
  598.     if (ptr == &mons[PM_CHAMELEON]) {
  599.         /* If you're protected with a ring, don't create
  600.          * any shape-changing chameleons -dgk
  601.          */
  602.         if (Protection_from_shape_changers)
  603.             mtmp->cham = 0;
  604.         else {
  605.             mtmp->cham = 1;
  606.             (void) newcham(mtmp, rndmonst());
  607.         }
  608.     } else if (ptr == &mons[PM_WIZARD_OF_YENDOR]) {
  609.         mtmp->iswiz = 1;
  610.         flags.no_of_wizards++;
  611.     } else if (ptr == &mons[PM_QUANTUM_MECHANIC])
  612.         mtmp = qname(mtmp);
  613.  
  614.     if(in_mklev) {
  615.         if(((is_ndemon(ptr)) ||
  616.             (ptr == &mons[PM_WUMPUS]) ||
  617. #ifdef WORM
  618.             (ptr == &mons[PM_LONG_WORM]) ||
  619. #endif
  620.             (ptr == &mons[PM_GIANT_EEL])) && rn2(5))
  621.             mtmp->msleep = 1;
  622.     } else {
  623.         if(byyou) {
  624.             pmon(mtmp);
  625.             set_apparxy(mtmp);
  626.         }
  627.     }
  628. #ifdef INFERNO
  629.     if(is_dprince(ptr)) {
  630.         mtmp->mpeaceful = mtmp->minvis = 1;
  631. # ifdef NAMED_ITEMS
  632.         if(uwep)
  633.         if(!strcmp(ONAME(uwep), "Excalibur"))
  634.             mtmp->mpeaceful = mtmp->mtame = 0;
  635. # endif
  636.     }
  637. #endif
  638. #ifdef WORM
  639.     if(ptr == &mons[PM_LONG_WORM] && getwn(mtmp))  initworm(mtmp);
  640. #endif
  641.     set_malign(mtmp);        /* having finished peaceful changes */
  642.     if(anything) {
  643.         if((ptr->geno & G_SGROUP) && rn2(2))
  644.         m_initsgrp(mtmp, mtmp->mx, mtmp->my);
  645.         else if(ptr->geno & G_LGROUP) {
  646.             if(rn2(3))  m_initlgrp(mtmp, mtmp->mx, mtmp->my);
  647.             else        m_initsgrp(mtmp, mtmp->mx, mtmp->my);
  648.         }
  649.     }
  650.  
  651.     if(is_armed(ptr))
  652.         m_initweap(mtmp);    /* equip with weapons / armour */
  653.     m_initinv(mtmp);        /* add on a few special items */
  654.  
  655.     return(mtmp);
  656. }
  657.  
  658. boolean
  659. enexto(cc, xx, yy, mdat)
  660. coord *cc;
  661. register xchar xx, yy;
  662. struct permonst *mdat;
  663. {
  664.     register xchar x,y;
  665.     coord foo[15], *tfoo;
  666.     int range, i;
  667.     int xmin, xmax, ymin, ymax;
  668.  
  669.     tfoo = foo;
  670.     range = 1;
  671.     do {    /* full kludge action. */
  672.         xmin = max(0, xx-range);
  673.         xmax = min(COLNO, xx+range);
  674.         ymin = max(0, yy-range);
  675.         ymax = min(ROWNO, yy+range);
  676.  
  677.         for(x = xmin; x <= xmax; x++)
  678.             if(goodpos(x, ymin, mdat)) {
  679.                 tfoo->x = x;
  680.                 (tfoo++)->y = ymin;
  681.                 if(tfoo == &foo[15]) goto foofull;
  682.             }
  683.         for(x = xmin; x <= xmax; x++)
  684.             if(goodpos(x, ymax, mdat)) {
  685.                 tfoo->x = x;
  686.                 (tfoo++)->y = ymax;
  687.                 if(tfoo == &foo[15]) goto foofull;
  688.             }
  689.         for(y = ymin+1; y < ymax; y++)
  690.             if(goodpos(xmin, y, mdat)) {
  691.                 tfoo->x = xmin;
  692.                 (tfoo++)->y = y;
  693.                 if(tfoo == &foo[15]) goto foofull;
  694.             }
  695.         for(y = ymin+1; y < ymax; y++)
  696.             if(goodpos(xmax, y, mdat)) {
  697.                 tfoo->x = xmax;
  698.                 (tfoo++)->y = y;
  699.                 if(tfoo == &foo[15]) goto foofull;
  700.             }
  701.         range++;
  702.         if(range > ROWNO && range > COLNO) return FALSE;
  703.     } while(tfoo == foo);
  704. foofull:
  705.     i = rn2((int)(tfoo - foo));
  706.     cc->x = foo[i].x;
  707.     cc->y = foo[i].y;
  708.     return TRUE;
  709. }
  710.  
  711. int
  712. goodpos(x, y, mdat)
  713. int x,y;
  714. struct permonst *mdat;
  715. {
  716.     if (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || MON_AT(x, y))
  717.         return 0;
  718.     if (x == u.ux && y == u.uy) return 0;
  719.     if (mdat) {
  720.         if (IS_POOL(levl[x][y].typ))
  721.         if (mdat == &playermon && (HLevitation || Wwalking))
  722.             return 1;
  723.         else    return (is_flyer(mdat) || is_swimmer(mdat));
  724.         if (passes_walls(mdat)) return 1;
  725.     }
  726.     if (!ACCESSIBLE(levl[x][y].typ)) return 0;
  727.     if (closed_door(x, y) && (!mdat || !amorphous(mdat)))
  728.         return 0;
  729.     if (sobj_at(BOULDER, x, y) && (!mdat || !throws_rocks(mdat)))
  730.         return 0;
  731.     return 1;
  732. }
  733.  
  734. #endif /* OVL1 */
  735. #ifdef OVLB
  736.  
  737. STATIC_OVL
  738. void
  739. rloc_to(mtmp, x, y)
  740. struct monst *mtmp;
  741. register int x,y;
  742. {
  743. #ifdef WORM        /* do not relocate worms */
  744.     if(mtmp->wormno && mtmp->mx) return;
  745. #endif
  746.     if(mtmp->mx != 0 && mtmp->my != 0)
  747.         remove_monster(mtmp->mx, mtmp->my);
  748.     place_monster(mtmp, x, y);
  749.     if(u.ustuck == mtmp){
  750.         if(u.uswallow) {
  751.             u.ux = x;
  752.             u.uy = y;
  753.             docrt();
  754.         } else    u.ustuck = 0;
  755.     }
  756.     pmon(mtmp);
  757.     set_apparxy(mtmp);
  758. }
  759.  
  760. #endif /* OVLB */
  761. #ifdef OVL2
  762.  
  763. void
  764. rloc(mtmp)
  765. struct monst *mtmp;
  766. {
  767.     register int x, y;
  768.  
  769.     /* if the wiz teleports away to heal, try the up staircase,
  770.        to block the player's escaping before he's healed */
  771.     if(!mtmp->iswiz || !goodpos(x = xupstair, y = yupstair, mtmp->data))
  772.        do {
  773.         x = rn1(COLNO-3,2);
  774.         y = rn2(ROWNO);
  775.        } while(!goodpos(x,y,mtmp->data));
  776.     rloc_to(mtmp, x, y);
  777. }
  778.  
  779. #endif /* OVL2 */
  780. #ifdef OVLB
  781.  
  782. void
  783. vloc(mtmp)
  784. struct monst *mtmp;
  785. {
  786.     register struct mkroom *croom;
  787.     register int x, y;
  788.  
  789.     for(croom = &rooms[0]; croom->hx >= 0; croom++)
  790.         if(croom->rtype == VAULT) {
  791.         x = rn2(2) ? croom->lx : croom->hx;
  792.         y = rn2(2) ? croom->ly : croom->hy;
  793.         if(goodpos(x, y, mtmp->data)) {
  794.             rloc_to(mtmp, x, y);
  795.             return;
  796.         }
  797.         }
  798.     rloc(mtmp);
  799. }
  800.  
  801. #endif /* OVLB */
  802. #ifdef OVL0
  803.  
  804. static int
  805. cmnum()    {    /* return the number of "common" monsters */
  806.  
  807.     int    i, count;
  808.  
  809.     for(i = count = 0; mons[i].mlet; i++)
  810.        if(!uncommon(&mons[i]))  count++;
  811.  
  812.     return(count);
  813. }
  814.  
  815. static int
  816. uncommon(ptr)
  817. struct    permonst *ptr;
  818. {
  819.     return (ptr->geno & (G_GENOD | G_NOGEN | G_UNIQ)) ||
  820.         (!Inhell ? ptr->geno & G_HELL : ptr->maligntyp > 0);
  821. }
  822.  
  823. #endif /* OVL0 */
  824. #ifdef OVL1
  825.  
  826. /* This routine is designed to return an integer value which represents
  827.  * an approximation of monster strength.  It uses a similar method of
  828.  * determination as "experience()" to arrive at the strength.
  829.  */
  830. static int
  831. mstrength(ptr)
  832. struct permonst *ptr;
  833. {
  834.     int    i, tmp2, n, tmp = ptr->mlevel;
  835.  
  836.     if(tmp > 49)        /* special fixed hp monster */
  837.         tmp = 2*(tmp - 6) / 4;
  838.  
  839. /*    For creation in groups */
  840.     n = (!!(ptr->geno & G_SGROUP));
  841.     n += (!!(ptr->geno & G_LGROUP)) << 1;
  842.  
  843. /*    For ranged attacks */
  844.     if (ranged_attk(ptr)) n++;
  845.  
  846. /*    For higher ac values */
  847.     n += (ptr->ac < 0);
  848.  
  849. /*    For very fast monsters */
  850.     n += (ptr->mmove >= 18);
  851.  
  852. /*    For each attack and "special" attack */
  853.     for(i = 0; i < NATTK; i++) {
  854.  
  855.         tmp2 = ptr->mattk[i].aatyp;
  856.         n += (tmp2 > 0);
  857.         n += (tmp2 == AT_MAGC);
  858.         n += (tmp2 == AT_WEAP && strongmonst(ptr));
  859.     }
  860.  
  861. /*    For each "special" damage type */
  862.     for(i = 0; i < NATTK; i++) {
  863.  
  864.         tmp2 = ptr->mattk[i].adtyp;
  865.         if((tmp2 == AD_DRLI) || (tmp2 == AD_STON)
  866. #ifdef POLYSELF
  867.                     || (tmp2 == AD_WERE)
  868. #endif
  869.                                 ) n += 2;
  870.         else if (ptr != &mons[PM_GRID_BUG]) n += (tmp2 != AD_PHYS);
  871.         n += ((ptr->mattk[i].damd * ptr->mattk[i].damn) > 23);
  872.     }
  873.  
  874. /*    Leprechauns are special cases.  They have many hit dice so they
  875.     can hit and are hard to kill, but they don't really do much damage. */
  876.     if (ptr == &mons[PM_LEPRECHAUN]) n -= 2;
  877.  
  878. /*    Finally, adjust the monster level  0 <= n <= 24 (approx.) */
  879.     if(n == 0) tmp--;
  880.     else if(n >= 6) tmp += ( n / 2 );
  881.     else tmp += ( n / 3 + 1);
  882.  
  883.     return((tmp >= 0) ? tmp : 0);
  884. }
  885.  
  886. void
  887. init_monstr()
  888. {
  889.     register int ct;
  890.  
  891.     for(ct = 0; mons[ct].mlet; ct++)
  892.         monstr[ct] = mstrength(&(mons[ct]));
  893. }
  894.  
  895. #endif /* OVL1 */
  896. #ifdef OVL0
  897.  
  898. struct    permonst *
  899. rndmonst()        /* select a random monster */
  900. {
  901.     register struct permonst *ptr;
  902.     register int i, ct;
  903.     register int zlevel;
  904.     static int NEARDATA minmlev, NEARDATA maxmlev, NEARDATA accept;
  905.     static long NEARDATA oldmoves = 0L;    /* != 1, starting value of moves */
  906. #ifdef REINCARNATION
  907.     static boolean NEARDATA upper;
  908.  
  909.     upper = (dlevel == rogue_level);
  910. #endif
  911.  
  912. #ifdef __GNULINT__
  913.     ptr = (struct permonst *)0; /* suppress "used uninitialized" warning */
  914. #endif
  915.     if(oldmoves != moves) {        /* must recalculate accept */
  916.         oldmoves = moves;
  917.         zlevel = u.uhave_amulet ? MAXLEVEL : dlevel;
  918.         if(cmnum() <= 0) {
  919. #ifdef DEBUG
  920.         pline("cmnum() fails!");
  921. #endif
  922.         return((struct permonst *) 0);
  923.         }
  924.  
  925.         /* determine the level of the weakest monster to make. */
  926.         minmlev = zlevel/6;
  927.         /* determine the level of the strongest monster to make. */
  928.         maxmlev = (zlevel + u.ulevel)>>1;
  929. /*
  930.  *    Find out how many monsters exist in the range we have selected.
  931.  */
  932.         accept = 0;
  933. #ifdef REINCARNATION
  934.         for(ct = (upper ? PM_APE : 0);
  935.             upper ? isupper(mons[ct].mlet) : mons[ct].mlet; ct++) {
  936. #else
  937.         for(ct = 0 ; mons[ct].mlet; ct++) {
  938. #endif
  939.         ptr = &(mons[ct]);
  940.         if(uncommon(ptr)) continue;
  941.         if(tooweak(ct, minmlev) || toostrong(ct, maxmlev))
  942.             continue;
  943.         accept += (ptr->geno & G_FREQ);
  944.         }
  945.     }
  946.  
  947.     if(!accept) {
  948. #ifdef DEBUG
  949.         pline("no accept!");
  950. #endif
  951.         return((struct permonst *) 0);
  952.     }
  953. /*
  954.  *    Now, select a monster at random.
  955.  */
  956.     ct = rnd(accept);
  957. #ifdef REINCARNATION
  958.     for(i = (upper ? PM_APE : 0);
  959.         (upper ? isupper(mons[i].mlet) : mons[i].mlet) && ct > 0; i++) {
  960. #else
  961.     for(i = 0; mons[i].mlet && ct > 0; i++) {
  962. #endif
  963.         ptr = &(mons[i]);
  964.         if(uncommon(ptr)) continue;
  965.         if(tooweak(i, minmlev) || toostrong(i, maxmlev))
  966.             continue;
  967.         ct -= (ptr->geno & G_FREQ);
  968.     }
  969.     if(ct > 0) {
  970. #ifdef DEBUG
  971.         pline("no count!");
  972. #endif
  973.         return((struct permonst *) 0);
  974.     }
  975.     return(ptr);
  976. }
  977.  
  978. #endif /* OVL0 */
  979. #ifdef OVL1
  980.  
  981. /*    The routine below is used to make one of the multiple types
  982.  *    of a given monster class.  It will return 0 if no monsters
  983.  *    in that class can be made.
  984.  */
  985.  
  986. struct permonst *
  987. mkclass(mlet)
  988. char    mlet;
  989. {
  990.     register int    first, last, num = 0;
  991.  
  992.     if(!mlet) {
  993.         impossible("mkclass called with null arg!");
  994.         return((struct permonst *) 0);
  995.     }
  996. /*    Assumption #1:    monsters of a given class are contiguous in the
  997.  *            mons[] array.
  998.  */
  999.     for(first = 0; mons[first].mlet != mlet; first++)
  1000.         if(!mons[first].mlet)    return((struct permonst *) 0);
  1001.  
  1002.     for(last = first; mons[last].mlet && mons[last].mlet == mlet; last++)
  1003.         if(!(mons[last].geno & (G_GENOD | G_NOGEN | G_UNIQ)))
  1004.         num += mons[last].geno & G_FREQ;
  1005.  
  1006.     if(!num) return((struct permonst *) 0);
  1007.  
  1008. /*    Assumption #2:    monsters of a given class are presented in ascending
  1009.  *            order of strength.
  1010.  */
  1011.     for(num = rnd(num); num > 0; first++)
  1012.         if(!(mons[first].geno & (G_GENOD | G_NOGEN | G_UNIQ))) { /* consider it */
  1013.         /* skew towards lower value monsters at lower exp. levels */
  1014.         if(adj_lev(&mons[first]) > (u.ulevel*2)) num--;
  1015.         num -= mons[first].geno & G_FREQ;
  1016.         }
  1017.     first--; /* correct an off-by-one error */
  1018.  
  1019.     return(&mons[first]);
  1020. }
  1021.  
  1022. int
  1023. adj_lev(ptr)    /* adjust strength of monsters based on dlevel and u.ulevel */
  1024. register struct permonst *ptr;
  1025. {
  1026.     int    tmp, tmp2;
  1027.  
  1028.     if((tmp = ptr->mlevel) > 49) return(50); /* "special" demons/devils */
  1029.     tmp2 = (dlevel - tmp);
  1030.     if(tmp2 < 0) tmp--;        /* if mlevel > dlevel decrement tmp */
  1031.     else tmp += (tmp2 / 5);        /* else increment 1 per five diff */
  1032.  
  1033.     tmp2 = (u.ulevel - ptr->mlevel);    /* adjust vs. the player */
  1034.     if(tmp2 > 0) tmp += (tmp2 / 4);        /* level as well */
  1035.  
  1036.     tmp2 = 3 * ptr->mlevel/ 2;        /* crude upper limit */
  1037.     return((tmp > tmp2) ? tmp2 : (tmp > 0 ? tmp : 0)); /* 0 lower limit */
  1038. }
  1039.  
  1040. #endif /* OVL1 */
  1041. #ifdef OVLB
  1042.  
  1043. struct permonst *
  1044. grow_up(mtmp)        /* mon mtmp "grows up" to a bigger version. */
  1045. register struct monst *mtmp;
  1046. {
  1047.     register int newtype;
  1048.     register struct permonst *ptr = mtmp->data;
  1049.  
  1050.     if (ptr->mlevel >= 50 || mtmp->mhpmax <= 8*mtmp->m_lev)
  1051.         return ptr;
  1052.     newtype = little_to_big(monsndx(ptr));
  1053.     if (++mtmp->m_lev >= mons[newtype].mlevel
  1054.                     && newtype != monsndx(ptr)) {
  1055.         if (mons[newtype].geno & G_GENOD) {
  1056.             pline("As %s grows up into %s, %s dies!",
  1057.                 mon_nam(mtmp),
  1058.                 an(mons[newtype].mname),
  1059.                 mon_nam(mtmp));
  1060.             mondied(mtmp);
  1061.             return (struct permonst *)0;
  1062.         }
  1063.         mtmp->data = &mons[newtype];
  1064.         mtmp->m_lev = mons[newtype].mlevel;
  1065.     }
  1066.     if (mtmp->m_lev > 3*mtmp->data->mlevel / 2)
  1067.         mtmp->m_lev = 3*mtmp->data->mlevel / 2;
  1068.     if (mtmp->mhp > mtmp->m_lev * 8)
  1069.         mtmp->mhp = mtmp->m_lev * 8;
  1070.     return(mtmp->data);
  1071. }
  1072.  
  1073. #endif /* OVLB */
  1074. #ifdef OVL1
  1075.  
  1076. int
  1077. mongets(mtmp, otyp)
  1078. register struct monst *mtmp;
  1079. register int otyp;
  1080. {
  1081.     register struct obj *otmp;
  1082.  
  1083.     if((otmp = (otyp) ? mksobj(otyp,FALSE) : mkobj(otyp,FALSE))) {
  1084.         if (mtmp->data->mlet == S_DEMON) {
  1085.         /* demons always get cursed objects */
  1086.         curse(otmp);
  1087.         }
  1088.         mpickobj(mtmp, otmp);
  1089.         return(otmp->spe);
  1090.     } else return(0);
  1091. }
  1092.  
  1093. #endif /* OVL1 */
  1094. #ifdef OVLB
  1095.  
  1096. #ifdef GOLEMS
  1097. int
  1098. golemhp(type)
  1099. int type;
  1100. {
  1101.     switch(type) {
  1102.         case PM_STRAW_GOLEM: return 20;
  1103.         case PM_ROPE_GOLEM: return 30;
  1104.         case PM_LEATHER_GOLEM: return 40;
  1105.         case PM_WOOD_GOLEM: return 50;
  1106.         case PM_FLESH_GOLEM: return 40;
  1107.         case PM_CLAY_GOLEM: return 50;
  1108.         case PM_STONE_GOLEM: return 60;
  1109.         case PM_IRON_GOLEM: return 80;
  1110.         default: return 0;
  1111.     }
  1112. }
  1113. #endif /* GOLEMS */
  1114.  
  1115. #endif /* OVLB */
  1116. #ifdef OVL1
  1117.  
  1118. /*
  1119.  *    Alignment vs. yours determines monster's attitude to you.
  1120.  *    ( some "animal" types are co-aligned, but also hungry )
  1121.  */
  1122. boolean
  1123. peace_minded(ptr)
  1124. register struct permonst *ptr;
  1125. {
  1126.     schar mal = ptr->maligntyp, ual = u.ualigntyp;
  1127.  
  1128.     if (always_peaceful(ptr)) return TRUE;
  1129.     if (always_hostile(ptr)) return FALSE;
  1130.  
  1131.     /* the monster is hostile if its alignment is different from the
  1132.      * player's */
  1133.     if (sgn(mal) != sgn(ual)) return FALSE;
  1134.  
  1135.     /* Negative monster hostile to player with Amulet. */
  1136.     if (mal < 0 && u.uhave_amulet) return FALSE;
  1137.  
  1138.     /* Last case:  a chance of a co-aligned monster being
  1139.      * hostile.  This chance is greater if the player has strayed
  1140.      * (u.ualign negative) or the monster is not strongly aligned.
  1141.      */
  1142.     return !!rn2(16 + (u.ualign < -15 ? -15 : u.ualign)) &&
  1143.         !!rn2(2 + abs(mal));
  1144. }
  1145.  
  1146. /* Set malign to have the proper effect on player alignment if monster is
  1147.  * killed.  Negative numbers mean it's bad to kill this monster; positive
  1148.  * numbers mean it's good.  Since there are more hostile monsters than
  1149.  * peaceful monsters, the penalty for killing a peaceful monster should be
  1150.  * greater than the bonus for killing a hostile monster to maintain balance.
  1151.  * Rules:
  1152.  *   it's bad to kill peaceful monsters, potentially worse to kill always-
  1153.  *    peaceful monsters
  1154.  *   it's never bad to kill a hostile monster, although it may not be good
  1155.  */
  1156. void
  1157. set_malign(mtmp)
  1158. struct monst *mtmp;
  1159. {
  1160.     schar mal = mtmp->data->maligntyp;
  1161.     boolean coaligned = (sgn(mal) == sgn(u.ualigntyp));
  1162.  
  1163.     if (always_peaceful(mtmp->data))
  1164.         mtmp->malign = -3*max(5,abs(mal));
  1165.     else if (always_hostile(mtmp->data)) {
  1166.         if (coaligned)
  1167.             mtmp->malign = 0;
  1168.         else
  1169.             mtmp->malign = max(5,abs(mal));
  1170.     } else if (coaligned) {
  1171.         if (mtmp->mpeaceful)
  1172.             mtmp->malign = -3*max(3,abs(mal));
  1173.         else    /* renegade */
  1174.             mtmp->malign = max(3,abs(mal));
  1175.     } else    /* not coaligned and therefore hostile */
  1176.         mtmp->malign = abs(mal);
  1177. }
  1178.  
  1179. #endif /* OVL1 */
  1180. #ifdef OVLB
  1181.  
  1182. static char NEARDATA syms[] = { 0, 1, RING_SYM, WAND_SYM, WEAPON_SYM, FOOD_SYM, GOLD_SYM,
  1183.     SCROLL_SYM, POTION_SYM, ARMOR_SYM, AMULET_SYM, TOOL_SYM, ROCK_SYM,
  1184.     GEM_SYM,
  1185. #ifdef SPELLS
  1186.     SPBOOK_SYM,
  1187. #endif
  1188.     S_MIMIC_DEF, S_MIMIC_DEF, S_MIMIC_DEF,
  1189. };
  1190.  
  1191. void
  1192. set_mimic_sym(mtmp)        /* KAA, modified by ERS */
  1193. register struct monst *mtmp;
  1194. {
  1195.     int roomno, rt;
  1196.     unsigned appear, ap_type;
  1197.     int s_sym;
  1198.     struct obj *otmp;
  1199.     int mx, my;
  1200.  
  1201.     if (!mtmp) return;
  1202.     mx = mtmp->mx; my = mtmp->my;
  1203.     mtmp->mimic = 1;
  1204.     roomno = inroom(mx, my);
  1205.     if (levl[mx][my].gmask) {
  1206.         ap_type = M_AP_GOLD;
  1207.         if (g_at(mx, my)->amount <= 32767)
  1208.             appear = g_at(mx, my)->amount;
  1209.         else
  1210.             appear = 32000 + rnd(767);
  1211.     }
  1212.     else if (OBJ_AT(mx, my)) {
  1213.         ap_type = M_AP_OBJECT;
  1214.         appear = level.objects[mx][my]->otyp;
  1215.     }
  1216.     else if (IS_DOOR(levl[mx][my].typ) ||
  1217.          IS_WALL(levl[mx][my].typ) ||
  1218.          levl[mx][my].typ == SDOOR ||
  1219.          levl[mx][my].typ == SCORR) {
  1220.         ap_type = M_AP_FURNITURE;
  1221.         appear = S_cdoor;
  1222.     }
  1223.     else if (is_maze_lev && rn2(2)) {
  1224.         ap_type = M_AP_OBJECT;
  1225.         appear = STATUE;
  1226.     }
  1227.     else if (roomno < 0) {
  1228.         ap_type = M_AP_OBJECT;
  1229.         appear = BOULDER;
  1230.     }
  1231.     else if ((rt = rooms[roomno].rtype) == ZOO || rt == VAULT) {
  1232.         ap_type = M_AP_GOLD;
  1233.         appear = rn2(100)+10;    /* number of gold pieces in pile */
  1234.     }
  1235. #ifdef ORACLE
  1236.     else if (rt == DELPHI) {
  1237.         if (rn2(2)) {
  1238.             ap_type = M_AP_OBJECT;
  1239.             appear = STATUE;
  1240.         }
  1241.         else {
  1242.             ap_type = M_AP_FURNITURE;
  1243.             appear = S_fountain;
  1244.         }
  1245.     }
  1246. #endif
  1247. #ifdef ALTARS
  1248.     else if (rt == TEMPLE) {
  1249.         ap_type = M_AP_FURNITURE;
  1250.         appear = S_altar;
  1251.     }
  1252. #endif
  1253.     /* We won't bother with beehives, morgues, barracks, throne rooms
  1254.      * since they shouldn't contain too many mimics anyway...
  1255.      */
  1256.     else if (rt >= SHOPBASE) {
  1257.         s_sym = get_shop_item(rt - SHOPBASE);
  1258.         if (s_sym < 0) {
  1259.             ap_type = M_AP_OBJECT;
  1260.             appear = -s_sym;
  1261.         }
  1262.         else {
  1263.             if (s_sym == RANDOM_SYM)
  1264.                 s_sym = syms[rn2(sizeof(syms)-2) + 2];
  1265.             goto assign_sym;
  1266.         }
  1267.     }
  1268.     else {
  1269.         s_sym = syms[rn2(sizeof syms)];
  1270. assign_sym:
  1271.         if (s_sym < 2) {
  1272.             ap_type = M_AP_FURNITURE;
  1273.             appear = s_sym ? S_upstair : S_dnstair;
  1274.         }
  1275.         else if (s_sym == GOLD_SYM) {
  1276.             ap_type = M_AP_GOLD;
  1277.             appear = rn2(100)+100;
  1278.         }
  1279.         else {
  1280.             ap_type = M_AP_OBJECT;
  1281.             if (s_sym == S_MIMIC_DEF)
  1282.                 appear = STRANGE_OBJECT;
  1283.             else {
  1284.                 otmp = mkobj( (char) s_sym, FALSE );
  1285.                 appear = otmp->otyp;
  1286.                 free((genericptr_t) otmp);
  1287.             }
  1288.         }
  1289.     }
  1290.     mtmp->m_ap_type = ap_type;
  1291.     mtmp->mappearance = appear;
  1292. }
  1293.  
  1294. #endif /* OVLB */
  1295.